package com.zhs.base.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhs.base.config.properties.BaiduMapProperties;
import com.zhs.base.dto.GeoCodeDto;
import com.zhs.base.dto.GeoInfoDto;
import com.zhs.base.service.BaseMapApiService;
import com.zhs.base.service.MapApiService;
import com.zhs.base.utils.HttpClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.Objects;

/**
 * 百度
 *
 * @author Java架构师之旅
 * @version 1.0
 * @date 2022年08月16日 17:16.
 */
@Slf4j
public class BaiduMapApiService extends BaseMapApiService implements MapApiService {
    private BaiduMapProperties baiduMapProperties;

    public void setBaiduMapProperties(final BaiduMapProperties baiduMapProperties) {
        this.baiduMapProperties = baiduMapProperties;
    }

    @Override
    public GeoCodeDto getGeocode(String address) {
        log.info("【地址编码  百度】入参: address={}", address);
        try {
            String getGeocoderLatitudeUrl = getGeocoderLatitudeMapUrl(super.encode(address));
            return super.defaultDealReturnJson(HttpClientUtils.get(getGeocoderLatitudeUrl));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private String getGeocoderLatitudeMapUrl(final String address) {
        return baiduMapProperties.getBaiduGeoUrl() + address + "&ak=" + baiduMapProperties.getBaiduKey();
    }

    @Override
    public GeoInfoDto getAddress(final GeoCodeDto geoCodeDto) {
        log.info("【逆地址编码 百度】入参,geoCodeDto{}", JSON.toJSONString(geoCodeDto));
        String urlString = getAddressUrl(geoCodeDto);
        try {
            final GeoInfoDto res = dealReturnAddJson(HttpClientUtils.get(urlString));
            log.info("【逆地址编码】res={}", JSON.toJSONString(res));
            return res;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private GeoInfoDto dealReturnAddJson(final String res) throws RuntimeException {
        if (StringUtils.isNotBlank(res)) {
            JSONObject jsonObject = JSON.parseObject(res);
            String status = jsonObject.getString("status");
            if (Objects.equals(NumberUtils.INTEGER_ZERO, Integer.valueOf(status))) {
                String formatted_address = "";
                JSONObject jsonObject_ = JSON.parseObject(jsonObject.getString("result"));
                formatted_address = jsonObject_.getString("formatted_address");
                if (jsonObject_.containsKey("poiRegions")) {
                    JSONArray poiRegions = (JSONArray) jsonObject_.get("poiRegions");
                    if (poiRegions.size() > NumberUtils.INTEGER_ZERO) {
                        JSONObject jobj = (JSONObject) poiRegions.get(NumberUtils.INTEGER_ZERO);
                        if (jobj.containsKey("name")) {
                            String name = (String) jobj.get("name");
                            formatted_address += " " + name;
                        }
                    } else {
                        formatted_address += " " + jsonObject_.get("sematic_description");
                    }
                }
                final GeoInfoDto geoInfoDto = new GeoInfoDto();
                geoInfoDto.setAddress(formatted_address);
                JSONObject addressComponent = JSON.parseObject(jsonObject_.getString("addressComponent"));
                if (null != addressComponent) {
                    geoInfoDto.setProvince(addressComponent.getString("province"));
                    geoInfoDto.setCity(addressComponent.getString("city"));
                    geoInfoDto.setDistrict(addressComponent.getString("district"));
                    geoInfoDto.setTownship(addressComponent.getString("town"));
                    geoInfoDto.setStreet(addressComponent.getString("street"));
                    geoInfoDto.setStreetNumber(addressComponent.getString("street_number"));
                }
                log.info("【逆地址编码】 成功 geoInfoDto={}", JSON.toJSONString(geoInfoDto));
                return geoInfoDto;
            }
            log.warn("【逆地址编码】 失败 message={}", jsonObject.getString("message"));
            throw new RuntimeException(jsonObject.getString("message"));
        }
        return null;
    }

    private String getAddressUrl(final GeoCodeDto geoCodeDto) {
        return baiduMapProperties.getBaiduReGeoUrl() + geoCodeDto.getLat() + "," + geoCodeDto.getLng() + "&ak=" + baiduMapProperties.getBaiduKey();
    }

    @Override
    public Integer getWeight() {
        return baiduMapProperties.getWeight();
    }
}
